﻿using System;
using System.Data;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;

namespace ImportEnt
{
    /// <summary>
    /// 序列化实现者
    /// </summary>
    public sealed class Serializer
    {
        /// <summary>
        /// 将object对象序列化成XML
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ObjectToXML(object o)
        {
            XmlSerializer ser = new XmlSerializer(o.GetType());
            MemoryStream mem = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(mem, Encoding.Default);
            ser.Serialize(writer, o);
            writer.Close();
            return Encoding.Default.GetString(mem.ToArray());
        }
        /// <summary>
        /// 将XML反序列化成对象
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static object XMLToObject(string s, Type t)
        {
            XmlSerializer mySerializer = new XmlSerializer(t);
            //((char)30).ToString() + ((char)0x1B).ToString() + "b" + ((char)3).ToString()
            if (s.Contains(((char)30).ToString())) s = s.Replace(((char)30).ToString(), string.Empty);
            if (s.Contains(((char)0x1B).ToString())) s = s.Replace(((char)0x1B).ToString(), string.Empty);
            if (s.Contains(((char)3).ToString())) s = s.Replace(((char)3).ToString(), string.Empty);
            StreamReader mem2 = new StreamReader(new MemoryStream(System.Text.Encoding.Default.GetBytes(s)), System.Text.Encoding.Default);
            return mySerializer.Deserialize(mem2);
        }


        /// <summary>
        /// 将object对象序列化成XML
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ObjectToXML<T>(T t)
        {
            return ObjectToXML<T>(t, Encoding.UTF8);
        }

        /// <summary>
        /// 将object对象序列化成XML
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ObjectToXML<T>(T t, Encoding encoding)
        {
            XmlSerializer ser = new XmlSerializer(t.GetType());
            Encoding utf8EncodingWithNoByteOrderMark = new UTF8Encoding(false);
            using (MemoryStream mem = new MemoryStream())
            {
                using (XmlTextWriter writer = new XmlTextWriter(mem, utf8EncodingWithNoByteOrderMark))
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");
                    ser.Serialize(writer, t, ns);
                    return encoding.GetString(mem.ToArray());
                }
            }
        }
        /// <summary>
        /// 将XML反序列化成对象
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T XMLToObject<T>(string source)
        {
            XmlSerializer mySerializer = new XmlSerializer(typeof(T));
            if (source.Contains(((char)30).ToString())) source = source.Replace(((char)30).ToString(), string.Empty);
            if (source.Contains(((char)0x1B).ToString())) source = source.Replace(((char)0x1B).ToString(), string.Empty);
            if (source.Contains(((char)3).ToString())) source = source.Replace(((char)3).ToString(), string.Empty);
            StreamReader mem2 = new StreamReader(new MemoryStream(System.Text.Encoding.Default.GetBytes(source)), System.Text.Encoding.Default);
            return (T)mySerializer.Deserialize(mem2);
        }

        /// <summary>
        /// 将XML反序列化成对象
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T XMLToObject<T>(string source,Encoding encode)
        {
            XmlSerializer mySerializer = new XmlSerializer(typeof(T));
            if (source.Contains(((char)30).ToString())) source = source.Replace(((char)30).ToString(), string.Empty);
            if (source.Contains(((char)0x1B).ToString())) source = source.Replace(((char)0x1B).ToString(), string.Empty);
            if (source.Contains(((char)3).ToString())) source = source.Replace(((char)3).ToString(), string.Empty);
            StreamReader mem2 = new StreamReader(new MemoryStream(System.Text.Encoding.Default.GetBytes(source)), System.Text.Encoding.Default);
            return (T)mySerializer.Deserialize(mem2);
        }


        /// <summary>
        /// 二进制方式序列化对象
        /// </summary>
        /// <param name="testUser"></param>
        public static string Serialize<T>(T obj)
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            StreamReader reader = new StreamReader(ms);

            return reader.ReadToEnd();
        }

        /// <summary>
        /// 二进制方式反序列化对象
        /// </summary>
        /// <returns></returns>
        public static T DeSerialize<T>(string str) where T : class
        {
            MemoryStream ms = new MemoryStream(System.Text.Encoding.Default.GetBytes(str));
            BinaryFormatter formatter = new BinaryFormatter();
            T t = formatter.Deserialize(ms) as T;
            return t;
        }

        /// <summary>
        /// 过滤XML以外的特殊字符
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static string FilterXMLOuter(string xml)
        {
            for (int i = 0; i < xml.Length; i++)
            {
                if (0 < xml[i] && xml[i] <= 0x1f
                    && xml[i] != 0x09
                    && xml[i] != 0x0a
                    && xml[i] != 0x0d)
                {
                    xml = xml.Replace(xml[i], (char)0x20);
                }
            }
            return xml;
        }


        public static string DataTable2Json(DataTable dt)
        {
            StringBuilder jsonBuilder = new StringBuilder();
            jsonBuilder.Append("{\"");
            jsonBuilder.Append(dt.TableName.ToString());
            jsonBuilder.Append("\":[");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                jsonBuilder.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    jsonBuilder.Append("\"");
                    jsonBuilder.Append(dt.Columns[j].ColumnName);
                    jsonBuilder.Append("\":\"");
                    jsonBuilder.Append(dt.Rows[i][j].ToString());
                    jsonBuilder.Append("\",");
                }
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
                jsonBuilder.Append("},");
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("]");
            jsonBuilder.Append("}");
            return jsonBuilder.ToString();
        }

        public static DataTable JsonToDataTable(string strJson)
        {
            //取出表名  
            Regex rg = new Regex(@"(?<={)[^:]+(?=:\[)", RegexOptions.IgnoreCase);
            string strName = rg.Match(strJson).Value;
            DataTable tb = null;
            //去除表名  
            strJson = strJson.Substring(strJson.IndexOf("[") + 1);
            strJson = strJson.Substring(0, strJson.IndexOf("]"));

            //获取数据  
            rg = new Regex(@"(?<={)[^}]+(?=})");
            MatchCollection mc = rg.Matches(strJson);
            for (int i = 0; i < mc.Count; i++)
            {
                string strRow = mc[i].Value;
                string[] strRows = strRow.Split(',');

                //创建表  
                if (tb == null)
                {
                    tb = new DataTable();
                    tb.TableName = strName;
                    foreach (string str in strRows)
                    {
                        DataColumn dc = new DataColumn();
                        string[] strCell = str.Split(':');
                        dc.ColumnName = strCell[0].ToString();
                        tb.Columns.Add(dc);
                    }
                    tb.AcceptChanges();
                }

                //增加内容  
                DataRow dr = tb.NewRow();
                for (int r = 0; r < strRows.Length; r++)
                {
                    dr[r] = strRows[r].Split(':')[1].Trim().Replace("，", ",").Replace("：", ":").Replace("\"", "");
                }
                tb.Rows.Add(dr);
                tb.AcceptChanges();
            }

            return tb;
        }

    }
}
